package cool.webstudy.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cool.webstudy.admin.constant.enums.CompetitionQuestionStatusEnum;
import cool.webstudy.admin.constant.enums.DelFlagEnum;
import cool.webstudy.admin.constant.enums.FileBisTypeEnum;
import cool.webstudy.admin.constant.enums.FileTypeTableNameEnum;
import cool.webstudy.admin.constant.enums.rescode.CompetitionQuestionResCodeEnum;
import cool.webstudy.admin.exception.BusinessException;
import cool.webstudy.admin.mapper.competition.question.CompetitionQuestionMapper;
import cool.webstudy.admin.model.dto.competition.question.CreateCompetitionQuestionDTO;
import cool.webstudy.admin.model.dto.competition.question.PaginationQueryCompetitionQuestionInfoListDTO;
import cool.webstudy.admin.model.dto.competition.question.QueryCompetitionQuestionDetailInfoDTO;
import cool.webstudy.admin.model.dto.competition.question.UpdateCompetitionQuestionDTO;
import cool.webstudy.admin.model.dto.file.UpdateFileRecordDTO;
import cool.webstudy.admin.model.dto.user.UserDetailInfoDTO;
import cool.webstudy.admin.model.po.competition.question.CompetitionQuestionPO;
import cool.webstudy.admin.model.vo.competition.question.PaginationQueryCompetitionQuestionInfoListVO;
import cool.webstudy.admin.model.vo.competition.question.QueryCompetitionQuestionRoughInfoVO;
import cool.webstudy.admin.model.vo.file.QueryFileRecordDetailInfoVO;
import cool.webstudy.admin.service.CompetitionQuestionService;
import cool.webstudy.admin.service.FileRecordService;
import cool.webstudy.admin.utils.UserDetailUtil;
import cool.webstudy.common.utils.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

/**
 * @author 莫振双
 * @date 2025/2/7 22:51
 * @description: 赛题服务实现类
 */
@Service
public class CompetitionQuestionServiceImpl implements CompetitionQuestionService {
    @Autowired
    private CompetitionQuestionMapper competitionQuestionMapper;
    @Autowired
    private FileRecordService fileRecordService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createCompetitionQuestion(CreateCompetitionQuestionDTO dto) {
        // 处理赛题文件
        QueryFileRecordDetailInfoVO fileRecordDetailInfo = fileRecordService.queryFileRecordDetailInfo(dto.getFileRecordUnCode());
        String fileName = fileRecordDetailInfo.getFileName();
        String unCode = UUIDUtil.getUUID();
        String filePath = fileRecordDetailInfo.getFilePath();
        UserDetailInfoDTO userDetailInfo = UserDetailUtil.getUserDetailInfo();
        CompetitionQuestionPO competitionQuestionPO = new CompetitionQuestionPO();
        competitionQuestionPO.setUnCode(unCode);
        competitionQuestionPO.setName(dto.getName());
        competitionQuestionPO.setDescription(dto.getDescription());
        competitionQuestionPO.setStatusFlag(CompetitionQuestionStatusEnum.UNUSED);
        competitionQuestionPO.setAutoFlag(dto.getAutoFlag());
        competitionQuestionPO.setFileName(fileName);
        competitionQuestionPO.setFilePath(filePath);
        competitionQuestionPO.setCreateBy(userDetailInfo.getAccount());
        competitionQuestionPO.setCreateTime(new Date());
        competitionQuestionPO.setUpdateBy(userDetailInfo.getAccount());
        competitionQuestionPO.setUpdateTime(new Date());
        competitionQuestionPO.setDelFlag(DelFlagEnum.NOT_DEL_FLAG.getFlag());
        try {
            competitionQuestionMapper.insert(competitionQuestionPO);
        } catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_CREATE);
        }
        //更新赛题文件记录信息
        UpdateFileRecordDTO updateFileRecordDTO = new UpdateFileRecordDTO();
        updateFileRecordDTO.setUnCode(dto.getFileRecordUnCode());
        updateFileRecordDTO.setTableName(FileTypeTableNameEnum.COMP_QUESTION.getFlag());
        updateFileRecordDTO.setTableUnCode(unCode);
        updateFileRecordDTO.setType(FileBisTypeEnum.COMP_QUESTION);
        fileRecordService.updateFileRecord(updateFileRecordDTO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCompetitionQuestion(UpdateCompetitionQuestionDTO dto) {
        // 处理赛题文件
        //判断是否修改了赛题文件
        QueryFileRecordDetailInfoVO fileRecordDetailInfo = null;
        if (StringUtils.isNotBlank(dto.getNewFileRecordUnCode())){
            fileRecordDetailInfo = fileRecordService.queryFileRecordDetailInfo(dto.getNewFileRecordUnCode());
            //删除旧的赛题文件记录
            fileRecordService.deleteFileRecord(FileTypeTableNameEnum.COMP_QUESTION.getFlag(), dto.getUnCode());
            //更新赛题文件记录信息
            UpdateFileRecordDTO updateFileRecordDTO = new UpdateFileRecordDTO();
            updateFileRecordDTO.setUnCode(dto.getNewFileRecordUnCode());
            updateFileRecordDTO.setTableName(FileTypeTableNameEnum.COMP_QUESTION.getFlag());
            updateFileRecordDTO.setTableUnCode(dto.getUnCode());
            updateFileRecordDTO.setType(FileBisTypeEnum.COMP_QUESTION);
            fileRecordService.updateFileRecord(updateFileRecordDTO);
        }else{
            fileRecordDetailInfo = fileRecordService.queryFileRecordDetailInfo(dto.getFileRecordUnCode());
        }
        UserDetailInfoDTO userDetailInfo = UserDetailUtil.getUserDetailInfo();
        LambdaUpdateWrapper<CompetitionQuestionPO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(CompetitionQuestionPO::getUnCode, dto.getUnCode())
                .set(CompetitionQuestionPO::getName, dto.getName())
                .set(CompetitionQuestionPO::getDescription, dto.getDescription())
                .set(CompetitionQuestionPO::getStatusFlag, dto.getStatusFlag())
                .set(CompetitionQuestionPO::getAutoFlag, dto.getAutoFlag())
                .set(CompetitionQuestionPO::getFileName, fileRecordDetailInfo.getFileName())
                .set(CompetitionQuestionPO::getFilePath, fileRecordDetailInfo.getFilePath())
                .set(CompetitionQuestionPO::getUpdateBy, userDetailInfo.getAccount())
                .set(CompetitionQuestionPO::getUpdateTime, new Date());
        try {
            competitionQuestionMapper.update(null, wrapper);
        } catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_UPDATE);
        }
        return true;
    }

    @Override
    public QueryCompetitionQuestionDetailInfoDTO queryCompetitionQuestionDetailInfo(String unCode) {
        LambdaQueryWrapper<CompetitionQuestionPO> wrapper = new LambdaQueryWrapper();
        wrapper.eq(CompetitionQuestionPO::getUnCode, unCode)
                .select(CompetitionQuestionPO::getUnCode,
                        CompetitionQuestionPO::getName,
                        CompetitionQuestionPO::getDescription,
                        CompetitionQuestionPO::getStatusFlag,
                        CompetitionQuestionPO::getAutoFlag,
                        CompetitionQuestionPO::getFilePath);
        CompetitionQuestionPO competitionQuestionPO = null;
        try {
            competitionQuestionPO = competitionQuestionMapper.selectOne(wrapper);
        } catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_QUERY);
        }
        if (Objects.isNull(competitionQuestionPO)) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_QUERY_NOT_EXIST);
        }
        //检查赛题文件是否存在
        try {
            if (!Files.exists(Paths.get(competitionQuestionPO.getFilePath()))) {
                throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_QUERY_FILE_NOT_EXIST);
            }
        } catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_QUERY_FILE);
        }
        QueryCompetitionQuestionDetailInfoDTO dto = new QueryCompetitionQuestionDetailInfoDTO();
        dto.setUnCode(competitionQuestionPO.getUnCode());
        dto.setName(competitionQuestionPO.getName());
        dto.setDescription(competitionQuestionPO.getDescription());
        dto.setStatusFlag(competitionQuestionPO.getStatusFlag());
        dto.setAutoFlag(competitionQuestionPO.getAutoFlag());
        dto.setFilePath(competitionQuestionPO.getFilePath());
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCompetitionQuestionStatus(CompetitionQuestionStatusEnum statusFlag, String unCode) {
        if (Objects.isNull(statusFlag) || StringUtils.isBlank(unCode)) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_UPDATE_STATUS);
        }
        try {
            LambdaUpdateWrapper<CompetitionQuestionPO> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(CompetitionQuestionPO::getUnCode, unCode)
                    .set(CompetitionQuestionPO::getStatusFlag, statusFlag);
            competitionQuestionMapper.update(null, wrapper);
        } catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_UPDATE_STATUS);
        }
    }

    @Override
    public Map<String, String> queryCompetitionQuestionRoughInfoMap() {
        LambdaQueryWrapper<CompetitionQuestionPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(CompetitionQuestionPO::getUnCode, CompetitionQuestionPO::getName);
        try {
            List<CompetitionQuestionPO> competitionQuestionPOList = competitionQuestionMapper.selectList(queryWrapper);
            if (Objects.isNull(competitionQuestionPOList)) {
                return Map.of();
            }
            Map<String, String> competitionQuestionRoughInfoMap = new HashMap<>();
            for (CompetitionQuestionPO competitionQuestionPO : competitionQuestionPOList) {
                competitionQuestionRoughInfoMap.put(competitionQuestionPO.getUnCode(), competitionQuestionPO.getName());
            }
            return competitionQuestionRoughInfoMap;
        } catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_QUERY);
        }
    }

    @Override
    public Page<PaginationQueryCompetitionQuestionInfoListVO> paginationQueryCompetitionQuestionInfoList(PaginationQueryCompetitionQuestionInfoListDTO dto) {
        Page<PaginationQueryCompetitionQuestionInfoListVO> paginationQueryCompetitionQuestionInfoListVOPage = new Page<>();
        Page<CompetitionQuestionPO> page = new Page<>(dto.getCurrent(), dto.getPageSize());
        LambdaQueryWrapper<CompetitionQuestionPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(dto.getContext()), CompetitionQuestionPO::getName, dto.getContext())
                .or().like(StringUtils.isNotBlank(dto.getContext()), CompetitionQuestionPO::getDescription, dto.getContext());
        try {
            Page<CompetitionQuestionPO> competitionQuestionPOPage = competitionQuestionMapper.selectPage(page, queryWrapper);
            if (Objects.isNull(competitionQuestionPOPage)) {
                return paginationQueryCompetitionQuestionInfoListVOPage;
            }
            //查询赛题文件记录与赛题记录业务主键映射关系
            Map<String, String> comQuesFileMap = fileRecordService.queryFileRecordAndTableUnCodeMap(FileTypeTableNameEnum.COMP_QUESTION.getFlag());
            List<PaginationQueryCompetitionQuestionInfoListVO> paginationQueryCompetitionQuestionInfoListVOList = new ArrayList<>();
            competitionQuestionPOPage.getRecords().forEach(competitionQuestionPO -> {
                PaginationQueryCompetitionQuestionInfoListVO vo = new PaginationQueryCompetitionQuestionInfoListVO();
                vo.setUnCode(competitionQuestionPO.getUnCode());
                vo.setName(competitionQuestionPO.getName());
                vo.setDescription(competitionQuestionPO.getDescription());
                vo.setStatusFlag(competitionQuestionPO.getStatusFlag());
                vo.setAutoFlag(competitionQuestionPO.getAutoFlag());
                vo.setFileName(competitionQuestionPO.getFileName());
                vo.setFileRecordUnCode(comQuesFileMap.get(competitionQuestionPO.getUnCode()));
                vo.setCreateBy(competitionQuestionPO.getCreateBy());
                vo.setCreateTime(competitionQuestionPO.getCreateTime());
                vo.setUpdateBy(competitionQuestionPO.getUpdateBy());
                vo.setUpdateTime(competitionQuestionPO.getUpdateTime());
                paginationQueryCompetitionQuestionInfoListVOList.add(vo);
            });
            paginationQueryCompetitionQuestionInfoListVOPage.setRecords(paginationQueryCompetitionQuestionInfoListVOList);
            paginationQueryCompetitionQuestionInfoListVOPage.setCurrent(competitionQuestionPOPage.getCurrent());
            paginationQueryCompetitionQuestionInfoListVOPage.setPages(competitionQuestionPOPage.getPages());
            paginationQueryCompetitionQuestionInfoListVOPage.setSize(competitionQuestionPOPage.getSize());
            paginationQueryCompetitionQuestionInfoListVOPage.setTotal(competitionQuestionPOPage.getTotal());
            return paginationQueryCompetitionQuestionInfoListVOPage;
        } catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_QUERY);
        }
    }

    @Override
    public List<QueryCompetitionQuestionRoughInfoVO> queryCompetitionQuestionRoughInfoList() {
        List<QueryCompetitionQuestionRoughInfoVO> queryCompetitionQuestionRoughInfoVOList = new ArrayList<>();
        LambdaQueryWrapper<CompetitionQuestionPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(CompetitionQuestionPO::getUnCode, CompetitionQuestionPO::getName);
        try {
            List<CompetitionQuestionPO> competitionQuestionPOList = competitionQuestionMapper.selectList(queryWrapper);
            if (Objects.isNull(competitionQuestionPOList)) {
                return queryCompetitionQuestionRoughInfoVOList;
            }
            for (CompetitionQuestionPO competitionQuestionPO : competitionQuestionPOList) {
                QueryCompetitionQuestionRoughInfoVO queryCompetitionQuestionRoughInfoVO = new QueryCompetitionQuestionRoughInfoVO();
                queryCompetitionQuestionRoughInfoVO.setUnCode(competitionQuestionPO.getUnCode());
                queryCompetitionQuestionRoughInfoVO.setName(competitionQuestionPO.getName());
                queryCompetitionQuestionRoughInfoVOList.add(queryCompetitionQuestionRoughInfoVO);
            }
            return queryCompetitionQuestionRoughInfoVOList;
        }catch (Exception e) {
            throw new BusinessException(CompetitionQuestionResCodeEnum.RC_ERROR_QUERY);
        }
    }
}
